package com.ly.demo.service.impl;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.ly.demo.entity.UserWxIdEntity;
import com.ly.demo.entity.ReceiveMessage;
import com.ly.demo.entity.SmResult;
import com.ly.demo.service.UserWxIdService;
import com.ly.demo.service.WeixinUserService;
import com.ly.demo.utils.WeixinMsgUtil;
import com.ly.demo.weixin.config.WeixinProperties;
import com.ly.demo.weixin.feign.WeixinFeign;
import com.ly.demo.weixin.feign.WeixinNeedTokenFeign;
import com.ly.demo.weixin.req.*;
import com.ly.demo.weixin.rsp.GetAccessTokenByOoauth2Rsp;
import com.ly.demo.weixin.rsp.QrCodeCreateRsp;
import com.ly.demo.weixin.rsp.SendMsgByTemplateRsp;
import com.ly.demo.weixin.rsp.WeixinUserInfoRsp;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.kafka.clients.admin.internals.AdminApiHandler;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.Map;

/**
 * @Author liuyang
 */
@Slf4j
@Service
public class WeixinUserServiceImpl implements WeixinUserService {

    @Resource
    private WeixinProperties weixinProperties;
    @Resource
    private RedisService redisService;
    @Resource
    private WeixinNeedTokenFeign weixinNeedTokenFeign;
    @Resource
    private UserWxIdService userWxIdService;
    @Resource
    private WeixinFeign weixinFeign;


    @Override
    public void checkSignature(String signature, String timestamp, String nonce) {
        String[] arr = new String[]{weixinProperties.getToken(), timestamp, nonce};
        Arrays.sort(arr);
        StringBuilder content = new StringBuilder();
        for (String str : arr) {
            content.append(str);
        }
        String tmpStr = DigestUtils.sha1Hex(content.toString());
        if (tmpStr.equals(signature)) {
            log.info("check success");
            return;
        }
        log.error("check fail");
        throw new RuntimeException("check fail");
    }

    @Override
    public String handleWeixinMsg(String requestBody) {
        ReceiveMessage receiveMessage = WeixinMsgUtil.msgToReceiveMessage(requestBody);
        // 扫码登录
        if (WeixinMsgUtil.isScanQrCode(receiveMessage)) {
            return handleScanLogin(receiveMessage);
        }
        // 关注
        if (WeixinMsgUtil.isEventAndSubscribe(receiveMessage)) {
            return receiveMessage.getReplyTextMsg("欢迎关注【liuyang】公众号");
        }
        return receiveMessage.getReplyTextMsg("收到（自动回复）");
    }

    @Override
    public SmResult getQrCode() {
        QrcodeCreateReq qrcodeCreateReq = new QrcodeCreateReq(300L, "QR_STR_SCENE", new ActionInfoReq(new SceneReq("login")));
        QrCodeCreateRsp qrCodeCreateRsp = weixinNeedTokenFeign.qrcodeCreate(qrcodeCreateReq);
        qrCodeCreateRsp.setQrCodeUrl(weixinProperties.getQrCodeUrlPrefix() + qrCodeCreateRsp.getTicket());
        return SmResult.ok(qrCodeCreateRsp);
    }

    @Override
    public SmResult sendMsgByTemplate(String openId, String param) {
        SendMsgByTemplateReq sendMsgByTemplateReq = new SendMsgByTemplateReq(openId, "m9PgRTcLjampZ67c09WE45oIN-7B5IIZ3LhKgwkwNpk", new WXParamReq(param));
        SendMsgByTemplateRsp rsp = weixinNeedTokenFeign.sendMsgByTemplate(sendMsgByTemplateReq);
        return rsp.isSuccess() ? SmResult.ok() : SmResult.fail(rsp.getErrcode(), rsp.getErrmsg());
    }

    @Override
    public SmResult getTmpTokenByCode(String code, HttpServletRequest request, HttpServletResponse response) {
        GetAccessTokenByOoauth2Req getAccessTokenByOoauth2Req = new GetAccessTokenByOoauth2Req();
        getAccessTokenByOoauth2Req.setCode(code);
        getAccessTokenByOoauth2Req.setAppid(weixinProperties.getAppid());
        getAccessTokenByOoauth2Req.setSecret(weixinProperties.getSecret());
        GetAccessTokenByOoauth2Rsp accessTokenByOoauth2 = weixinFeign.getAccessTokenByOoauth2(getAccessTokenByOoauth2Req);


        return SmResult.ok(accessTokenByOoauth2);
    }

    /**
     * 处理扫码登录
     *
     * @param receiveMessage
     * @return
     */
    private String handleScanLogin(ReceiveMessage receiveMessage) {
        String openId = receiveMessage.getFromUserName();
        String qrCodeTicket = receiveMessage.getTicket();
        WeixinUserInfoRsp weixinUserInfoRsp = weixinNeedTokenFeign.userInfo(new UserInfoReq(openId));
        weixinUserInfoRsp.setUnionid("test");
        if (StrUtil.isNotEmpty(weixinUserInfoRsp.getErrmsg()) || StrUtil.isEmpty(weixinUserInfoRsp.getUnionid())) {
            log.error("[handleScanLogin] fail - weixinUserInfoRsp:{}", weixinUserInfoRsp);
            return "success";
        }
        UserWxIdEntity userWxIdEntity = userWxIdService.getByUnionId(weixinUserInfoRsp.getUnionid());
        if (ObjUtil.isNotEmpty(userWxIdEntity)) {
            userWxIdEntity.setServiceNumberId(openId);
            userWxIdService.updateById(userWxIdEntity);
            redisService.setQrCodeTicket(qrCodeTicket, JSONUtil.toJsonStr(SmResult.ok(MapUtil.of("token", "123"))));
        } else {
            Map<Object, Object> map = MapUtil.builder().put("unionId", weixinUserInfoRsp.getUnionid()).put("openId", weixinUserInfoRsp.getOpenid()).build();
            redisService.setQrCodeTicket(qrCodeTicket, JSONUtil.toJsonStr(SmResult.fail(401, "先去绑定手机号").data(map)));
        }
        return "success";
    }
}
